using System;

namespace Pvf.Core
{
    /// <summary>
    /// 对象忽略当前属性
    /// </summary>
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
    public sealed class PvfIngoreAttribute : Attribute
    {

    }

    /// <summary>
    /// 将会获取到闭合字段
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    public sealed class PvfClosedAttribute : Attribute
    {
        /// <summary>
        /// 
        /// </summary>
        /// <value></value>
        public int ClosedFieldKey { get; set; } = -1;


        /// <summary>
        /// 
        /// </summary>
        /// <value></value>
        public string ClosedFieldName { get; set; }

        /// <summary>
        /// 可选的? 如果是的话 那么会一直读取 知道获取到闭合字段或者结尾
        /// </summary>
        public bool Optional { get; set; }
    }

    /// <summary>
    /// 如果添加这个特性 那么这个类所有属性会按顺序初始化
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public sealed class PvfRequiredAttribute : Attribute
    {

    }

    /// <summary>
    /// 如果添加这个字段 那么这个字段不会读取数据 常用于对象中的bool属性
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    public sealed class PvfEmptyAttribute : Attribute
    {

    }

    /// <summary>
    /// 模块进入点
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public sealed class ModuleEntryAttribute : Attribute
    {
        public ModuleEntryAttribute(string name)
        {
            Name = name;
        }

        /// <summary>
        /// 模块名称
        /// </summary>
        public string Name { get; }
    }

    /// <summary>
    /// Pvf属性字段的默认值(一般用在对象的静态属性上)
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    public sealed class PvfDefaultValueAttribute : Attribute
    {

    }

    /// <summary>
    /// Pvf自定义对象转换器
    /// </summary>
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public sealed class PvfCustomConverterAttribute : Attribute
    {
        public PvfCustomConverterAttribute(Type type)
        {
            InType = type;
        }

        public Type InType { get; }
    }

    /// <summary>
    /// 适用于接口/抽象类作为对象属性,然后根据key实例化不同的子类对象
    /// 注意:如果对象属性不是一个集合 那么需要添加Virutal关键字
    /// </summary>
    [AttributeUsage(AttributeTargets.Property , Inherited = false, AllowMultiple = false)]
    public sealed class PvfDynamicElementAttribute : Attribute
    {
        public PvfDynamicElementAttribute(Type enumType, Type objType)
        {
            EnumType = enumType;
            FallbackImplType = objType;
        }

        /// <summary>
        /// Enum类型
        /// </summary>
        public Type EnumType { get; }

        /// <summary>
        /// 默认子类
        /// </summary>
        public Type FallbackImplType { get; }
    }

    /// <summary>
    /// enum中字段映射到具体子类
    /// </summary>
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Enum, Inherited = false, AllowMultiple = false)]
    public sealed class PvfDynamicElementMapAttribute : Attribute
    {
        public PvfDynamicElementMapAttribute(Type objType)
        {
            ImplType = objType;
        }

        /// <summary>
        /// 子类
        /// </summary>
        public Type ImplType { get; }
    }


    /// <summary>
    /// 扩展字段
    /// </summary>
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    public sealed class PvfFieldsAttribute : Attribute
    {
        public PvfFieldsAttribute(bool includeSourceField, params string[] fields)
        {
            IncludeSourceField = includeSourceField;
            Fields = fields;
        }

        /// <summary>
        /// 如果为true 那么原来的字段值也要读取
        /// </summary>
        public bool IncludeSourceField { get; }

        /// <summary>
        /// 
        /// </summary>
        public string[] Fields { get; }
    }

    /// <summary>
    /// 仅用于List 有多个相同的字段 但是都会添加到列表中
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    public sealed class PvfObjectSetAttribute : Attribute
    {

    }
}
